#pragma once

#include "common_data.h"
#include "broker.h"

#include <stddef.h>
#include <stdio.h>
#include <ev.h>
#include <time.h>

#ifdef __cplusplus
extern "C" {
#endif

#define MAIN_TIMER_PERIOD 1.0
#define ACTION_TIMER_PERIOD 1.0


typedef struct{
  STATE_t curr_state;
  EVENT_t curr_event;

  struct bcshm_t shm;
  ftc_tlm_t ftc_tlm;
  flight_task_t flight_task;

} STATE_MACHINE_t;

typedef void (*ACTION_PTR_t)(STATE_MACHINE_t* sm);

typedef struct{
  STATE_t state;
  ACTION_PTR_t action;
} TRANSIT_t;

typedef struct{
  ev_timer timer;
  STATE_MACHINE_t* sm;
}SM_TIMER_t;

extern const ACTION_PTR_t actions[ACTION_MAX];

extern const TRANSIT_t transition_table[STATE_MAX][EVENT_MAX];

EVENT_t getEvent(STATE_MACHINE_t* sm);
void stateMachineTransit(STATE_MACHINE_t* sm);
void stateMachineKernel();

static void main_timer_cb(struct ev_loop *loop, ev_timer *w, int revents);
static void timer1_cb(struct ev_loop *loop, ev_timer *w, int revents);
static void timer2_cb(struct ev_loop *loop, ev_timer *w, int revents);

void action_timer1(STATE_MACHINE_t* sm);
void action_takeoff(STATE_MACHINE_t* sm);
void action_timer2(STATE_MACHINE_t* sm);
void action_land(STATE_MACHINE_t* sm);
void action_reset(STATE_MACHINE_t* sm);
void action_land_reset(STATE_MACHINE_t* sm);
void action_reinit(STATE_MACHINE_t* sm);

int time_diff(int rqr_time);

#ifdef __cplusplus
};
#endif

